﻿/*   
    Copyright (C) 2009 Galaktika Corporation ZAO

    This file is a part of Galaktika.BusinessMonitor
 
    Galaktika.BusinessMonitor is a free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
      
    You should have received a copy of the GNU General Public License
    along with Galaktika.BusinessMonitor.  If not, see <http://www.gnu.org/licenses/>.
  
    If GPL v.3 is not suitable for your products or company,
    Galaktika Corp provides Galaktika.BusinessMonitor under a flexible commercial license
    designed to meet your specific usage and distribution requirements.
    If you have already obtained a commercial license from Galaktika Corp,
    you can use this file under those license terms.
*/

using System;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.ComponentModel;
using Galaktika.BI.Runtime;
using Ranet.AgOlap.Controls.ContextMenu;
using Ranet.AgOlap.Controls.General;
using Galaktika.BI.Silverlight.Controls.Charting;
using Visifire.Charts;
using Galaktika.BI.Silverlight.Intermediate;
using Galaktika.BI.Addin.VisifireChart.Runtime;
using System.Globalization;

namespace Galaktika.BI.Charting
{
    public class ChartSeries : DataSeries, IEditableObject
    {
        private Border border = null;
        public const string VALUE_COLUMN_NAME = "_$Value";

        public object Clone()
        {
            return (ChartSeries)this.MemberwiseClone();
        }

        public override string ToString()
        {
            string seriesName = this.AName;

            if (!this.IsSeriesCompatible)
                seriesName = "(incompatible) " + seriesName;

            return seriesName;
        }

        #region Properties
        [DefaultValue("")]
        public string AName { get; set; }

        //[Browsable(false)]
        public bool IsSeriesCompatible { get; set; }

        private int m_DataSeriesIndex;
        [DefaultValue(0)]
        /// <summary>
        /// Индекс отображаемой серии из реального источника данных
        /// </summary>
        public int ADataSeriesIndex
        {
            get
            {
                return m_DataSeriesIndex;
            }
            set
            {
                if (value >= 0)
                {
                    m_DataSeriesIndex = value;
                }
            }
        }

        /// <summary>
        /// Имя столбца реляционного источника данных, из которого будут выбираться значения
        /// </summary>
        [DefaultValue(typeof(string), VALUE_COLUMN_NAME)]
        public string AValueColumnName { get; set; }

        /// <summary>
        /// Имя столбца реляционного источника данных, из которого будут выбираться аргументы
        /// </summary>
        [DefaultValue("")]
        public string AArgumentColumnName { get; set; }

        #endregion Additional Properties               
    
        #region Appearance Properties

        private ViewTypeCharting m_ViewType = ViewTypeCharting.Column;
        public ViewTypeCharting AViewType
        {
            get { return m_ViewType; }
            set { m_ViewType = value; }
        }

        private bool m_Visible = true;
        public bool AVisible
        {
            get { return m_Visible; }
            set { m_Visible = value; }
        }

        private bool m_ShowInLegend = true;
        public bool AShowInLegend
        {
            get { return m_ShowInLegend; }
            set { m_ShowInLegend = value; }
        }

        [DefaultValue("")]
        public string ALegendText { get; set; }

        private string m_Transparency = "1";
        public string ATransparency
        {
            get { return m_Transparency; }
            set { m_Transparency = value; }
        }

        private bool m_EnabledSelection = true;
        public bool AEnabledSelection
        {
            get { return m_EnabledSelection; }
            set { m_EnabledSelection = value; }
        }
        
        #endregion Appearance Properties
                               
        #region Label Properties

        private bool m_LabelVisible = true;
        public bool ALabelVisible 
        {
            get { return m_LabelVisible; }
            set { m_LabelVisible = value; }
        }

        private Color m_LabelBackColor = Colors.Transparent;
        //[DefaultValue(typeof(Color), "White")]
        public Color ALabelBackColor
        {
            get
            {
                return m_LabelBackColor;
            }
            set
            {
                m_LabelBackColor = value;
            }
        }

        private Color m_LabelTextColor = Colors.Black;
        //[DefaultValue(typeof(Color), "Black")]
        public Color ALabelTextColor
        {
            get
            {
                return m_LabelTextColor;
            }
            set
            {
                m_LabelTextColor = value;
            }
        }

        private LineStyles m_LabelLineStyle = LineStyles.Solid;
        //[DefaultValue(typeof(Color), "White")]
        public LineStyles ALabelLineStyle
        {
            get
            {
                return m_LabelLineStyle;
            }
            set
            {
                m_LabelLineStyle = value;
            }
        }

        private int m_LabelLineThickness = 1;
        [DefaultValue(1)]
        public int ALabelLineThickness
        {
            get
            {
                return m_LabelLineThickness;
            }
            set
            {
                if (value > 0)
                {
                    m_LabelLineThickness = value;
                }
            }
        }

        private bool m_LabelLineVisible = false;
        public bool ALabelLineVisible
        {
            get { return m_LabelLineVisible; }
            set { m_LabelLineVisible = value; }
        }

        private Color m_LabelLineColor = Colors.Black;
        //[DefaultValue(typeof(Color), "Black")]
        public Color ALabelLineColor
        {
            get
            {
                return m_LabelLineColor;
            }
            set
            {
                m_LabelLineColor = value;
            }
        }
        
        private Font m_LabelFont = new Font();
        public Font ALabelFont
        {
            get
            {
                return this.m_LabelFont;
            }
            set
            {
                this.m_LabelFont = value;
            }
        }

        private LabelStyles m_LabelPosition;
        public LabelStyles? ALabelPosition
        {
            get { return m_LabelPosition; }
            set 
            {
                if (value.HasValue)
                    m_LabelPosition = value.Value;
            }

        }

        public string AXValueFormat { get; set; }

        public string AYValueFormat { get; set; }

        public string AZValueFormat { get; set; }

        public double APieMinRadius 
        { 
            get; 
            set; 
        }
       
        #endregion Label Properties         
      

        public RanetChart Owner2
        {
            get; set;
        }
        #region Private Methods       
        
        // Разбивает строку на элементы, представляющие собой целые числа - индексы
        private int[] ParseFilter(string stringFilter)
        {
            List<int> indexesInFilterResult = new List<int>();

            List<string> filterParts = new List<string>(stringFilter.Trim().Split(','));
            foreach (string filterPart in filterParts)
            {
                indexesInFilterResult.AddRange(this.ParsePartFilter(filterPart));
            }

            return indexesInFilterResult.ToArray();
        }

        // Возвращает диапазон индексов из части фильтра
        private int[] ParsePartFilter(string stringPartFilter)
        {
            List<int> indexesInFilterResult = new List<int>();
            List<string> indexesRange = new List<string>(stringPartFilter.Trim().Split('-'));
            if (indexesRange.Count > 0)
            {
                int indexMin = this.GetMinIndex(indexesRange);
                int indexMax = this.GetMaxIndex(indexesRange);
                for (int indexValue = indexMin; indexValue <= indexMax; indexValue++)
                {
                    indexesInFilterResult.Add(indexValue);
                }
            }
            return indexesInFilterResult.ToArray();
        }

        // Возвращает минимальное целое значение из списка строк indexesRange
        private int GetMinIndex(List<string> indexesRange)
        {
            int indexMinResult = int.MaxValue;
            foreach (string indexString in indexesRange)
            {
                int indexValue = 0;
                if (int.TryParse(indexString, out indexValue))
                {
                    if (indexValue < indexMinResult)
                    {
                        indexMinResult = indexValue;
                    }
                }
            }

            return indexMinResult;
        }

        // Возвращает максимальное целое значение из списка строк indexesRange
        private int GetMaxIndex(List<string> indexesRange)
        {
            int indexMaxResult = int.MinValue;
            foreach (string indexString in indexesRange)
            {
                int indexValue = 0;
                if (int.TryParse(indexString, out indexValue))
                {
                    if (indexValue > indexMaxResult)
                    {
                        indexMaxResult = indexValue;
                    }
                }
            }

            return indexMaxResult;
        }

        #endregion Private Methods

        #region Public Methods       

        public DataSeries GetMappedSeries(ChartSeries chartSeries, DataSeries series)
        {
            if (series.RenderAs == RenderAs.Pie || series.RenderAs == RenderAs.Doughnut)
            {
                series.StartAngle = 270;
            }
            if (chartSeries.ALabelBackColor != Colors.Transparent)
                series.LabelBackground = new SolidColorBrush(chartSeries.ALabelBackColor);
            if (chartSeries.ALabelFont != null && !string.IsNullOrEmpty(chartSeries.ALabelFont.FamilyName))
                series.LabelFontFamily = new FontFamily(chartSeries.ALabelFont.FamilyName);
            series.LabelLineEnabled = chartSeries.ALabelLineVisible;
            if (chartSeries.ALabelLineVisible)
                series.LabelLineColor = new SolidColorBrush(chartSeries.ALabelLineColor);
            series.LabelLineStyle = chartSeries.ALabelLineStyle;
            series.LabelLineThickness = chartSeries.ALabelLineThickness;            
            series.LabelStyle = chartSeries.ALabelPosition;
            series.LabelEnabled = chartSeries.ALabelVisible;
            series.XValueFormatString = AXValueFormat;
            series.YValueFormatString = AYValueFormat;
            series.ZValueFormatString = AZValueFormat;
            series.PieMinRadius = chartSeries.APieMinRadius;
            if (!string.IsNullOrEmpty(chartSeries.LegendText))
                series.LegendText = chartSeries.ALegendText;
            double result;
            if (double.TryParse(chartSeries.ATransparency, NumberStyles.Any,CultureInfo.InvariantCulture, out result))
            {
                if (result > 1)
                    series.Opacity = result/100;
                else
                    series.Opacity = result;
            }
            series.SelectionEnabled = chartSeries.AEnabledSelection;
            series.ShowInLegend = chartSeries.AShowInLegend;
            series.Enabled = chartSeries.AVisible;                        
            return series;
        }

        #endregion Public Methods
        

        public DataSeries MappedSeries { get; set; }

        public ChartSeries()
        {
            ALabelVisible = true;           
            ALabelLineVisible = true;           
            AName = string.Empty;
        }


        #region IEditableObject Members

        public void BeginEdit()
        {

        }

        public void CancelEdit()
        {

        }

        public void EndEdit()
        {          
        }

        #endregion
    }
}
